package reader

import (
	"github.com/kordar/formatter"
	"github.com/kordar/gocrud"
	"gorm.io/gorm"
)

type QueryReader struct {
	pageSize int
	page     int
	query    *gorm.DB
	Formatter
}

func NewQueryReader(db *gorm.DB, page int, pageSize int) QueryReader {
	return QueryReader{
		pageSize:  pageSize,
		page:      page,
		query:     db,
		Formatter: Formatter{},
	}
}

func (reader *QueryReader) SearchVO(target interface{}, params map[string]interface{}) gocrud.SearchVO {
	if params == nil {
		params = make(map[string]interface{})
	}
	params["page"] = reader.page
	params["pageSize"] = reader.pageSize
	_, count := reader.ReaderWithCount(target)
	list := formatter.ToDataList(target, params)
	return gocrud.NewSearchVO(list, count)
}

func (reader *QueryReader) ReaderWithCount(container interface{}) (*gorm.DB, int64) {
	count := reader.Count()
	query := reader.query.Offset((reader.page - 1) * reader.pageSize).Limit(reader.pageSize)
	return query.Find(container), count
}

func (reader *QueryReader) Reader(container interface{}) *gorm.DB {
	query := reader.query.Offset((reader.page - 1) * reader.pageSize).Limit(reader.pageSize)
	return query.Find(container)
}

func (reader *QueryReader) ReaderAll(container interface{}) *gorm.DB {
	query := reader.query
	return query.Find(container)
}

func (reader *QueryReader) Count() int64 {
	var count int64
	reader.query.Count(&count)
	return count
}

func (reader *QueryReader) View(result interface{}, fun func(item interface{}) map[string]interface{}) map[string]interface{} {
	return fun(result)
}
